using UnityEngine;
using System.Collections;
using System.Collections.Generic;



public class TextureInfo
{
	public Texture	m_rTextureAtlas;
	public Rect		m_rectNormalizedFrame;
	public bool		m_bTrimmed;
	public Rect		m_rectSpriteSourceSize;
	public Vector2	m_vOriginalSize;
}


public class BM_TextureManager : MonoBehaviour
{
	#region Members
	
	private Dictionary<string, Texture>			m_dictTextures = null;
	private Dictionary<string, TextureInfo>		m_dictTextureData = null;
	
	#endregion
	
	
	public void Awake()
	{
		m_rManagerReference = this;
		
		m_dictTextures = new Dictionary<string, Texture>();
		m_dictTextureData = new Dictionary<string, TextureInfo>();
	}
	
	public void Start() { }

	
	private bool UseHDTextures()
	{
		bool bRVal = false;
		
//#if UNITY_IPHONE
//		
//		if( iPhone.generation == iPhoneGeneration.iPad1Gen ||
//			iPhone.generation == iPhoneGeneration.iPhone4 ||
//			iPhone.generation == iPhoneGeneration.iPhone3GS ||
//			iPhone.generation == iPhoneGeneration.iPhone3G ||
//			iPhone.generation == iPhoneGeneration.iPodTouch4Gen ||
//			iPhone.generation == iPhoneGeneration.iPodTouch3Gen ||
//			iPhone.generation == iPhoneGeneration.iPodTouch2Gen ||
//			iPhone.generation == iPhoneGeneration.iPodTouch1Gen )
//		{
//			bRVal = false;
//		}
//		else
//			bRVal = true;
//		
//#elif UNITY_ANDROID
//		
//		float fSize = 0.0f;
//		if(SV_Utils.DeviceOrientationType == SV_Utils.DeviceOrientation.ORIENTATION_LANDSCAPE)
//			fSize = SV_Utils.ScreenWidth;
//		else
//			fSize = SV_Utils.ScreenHeight;
//		
//		if(fSize >= 1280)
//			bRVal = true;
//		
//#else
//		
//		bRVal = true;
//#endif
		
		return bRVal;
	}
	
	public float GetHDTextureScaleFactor()
	{
		float fRVal = 1.5f;
		
		if(UseHDTextures())
			fRVal = 1.0f;
		
		return fRVal;
	}
	
	
	public void LoadTexture(TextureId eTextureId)
	{
		string strTextureName = BM_Common.GetTextureName(eTextureId);
		
		if(UseHDTextures())
			strTextureName += "-hd";
		
				
		Texture rTextureToLoad = null;
		if(!m_dictTextures.TryGetValue(strTextureName, out rTextureToLoad))
		{
			Texture rTexture = Resources.Load(strTextureName, typeof(Texture)) as Texture;
			TextAsset vFile = Resources.Load(strTextureName, typeof(TextAsset)) as TextAsset;
			
			if(rTexture != null && vFile != null)
			{
				string jsonString = vFile.text;
				Hashtable decodedHash = jsonString.hashtableFromJson();
				IDictionary dictFrames = (IDictionary)decodedHash["frames"];
				foreach(DictionaryEntry item in dictFrames)
				{
					// extract the info we need from the TexturePacker json file, mainly uvRect and size
					IDictionary frame = (IDictionary)((IDictionary)item.Value)["frame"];
					float fFrameX = float.Parse(frame["x"].ToString());
					float fFrameY = float.Parse(frame["y"].ToString());
					float fFrameW = float.Parse(frame["w"].ToString());
					float fFrameH = float.Parse(frame["h"].ToString());
		
					// for trimming support
					IDictionary spriteSourceSize = (IDictionary)((IDictionary)item.Value)["spriteSourceSize"];
					float fSpriteSourceSizeX = float.Parse(spriteSourceSize["x"].ToString());
					float fSpriteSourceSizeY = float.Parse(spriteSourceSize["y"].ToString());
					float fSpriteSourceSizeW = float.Parse(spriteSourceSize["w"].ToString());
					float fSpriteSourceSizeH = float.Parse(spriteSourceSize["h"].ToString());
		
					bool bTrimmed = (bool)((IDictionary)item.Value)["trimmed"];
					
					Vector2 vOriginalSize = Vector2.zero;
					IDictionary originalSize = (IDictionary)((IDictionary)item.Value)["sourceSize"];
					vOriginalSize.x = float.Parse(originalSize["w"].ToString())*BM_Utils.ScaleFactor;
					vOriginalSize.y = float.Parse(originalSize["h"].ToString())*BM_Utils.ScaleFactor;
					
					TextureInfo textureInfo = new TextureInfo();
					textureInfo.m_rTextureAtlas = rTexture;
					textureInfo.m_rectNormalizedFrame = new Rect(fFrameX/rTexture.width, (rTexture.height-fFrameY-fFrameH)/rTexture.height, fFrameW/rTexture.width, fFrameH/rTexture.height);
					textureInfo.m_rectSpriteSourceSize = new Rect(fSpriteSourceSizeX*BM_Utils.ScaleFactor, fSpriteSourceSizeY*BM_Utils.ScaleFactor, fSpriteSourceSizeW*BM_Utils.ScaleFactor*GetHDTextureScaleFactor(), fSpriteSourceSizeH*BM_Utils.ScaleFactor*GetHDTextureScaleFactor());
					textureInfo.m_bTrimmed = bTrimmed;
					textureInfo.m_vOriginalSize = vOriginalSize;
					
					m_dictTextureData.Add(item.Key.ToString(), textureInfo);
				}
				
				m_dictTextures.Add(strTextureName, rTexture);
		
				// unload the asset
				Resources.UnloadAsset(vFile);
				vFile = null;
			}
			else if(Debug.isDebugBuild)
				Debug.LogWarning("CM_TextureManager.LoadTexture: impossibile trovare il file " + strTextureName);
		}
	}
	
	public void UnloadTexture(TextureId eTextureId)
	{
		string strTextureName = BM_Common.GetTextureName(eTextureId);
		
		if(UseHDTextures())
			strTextureName += "-hd";
		
		Texture rTextureToUnload = null;
		if(m_dictTextures.TryGetValue(strTextureName, out rTextureToUnload))
		{
			Dictionary<string, TextureInfo> dictTextureDataCopy = m_dictTextureData;
			m_dictTextureData = new Dictionary<string, TextureInfo>();
			
			foreach(KeyValuePair<string,TextureInfo> item in dictTextureDataCopy)
			{
				if(item.Value.m_rTextureAtlas.GetInstanceID() != rTextureToUnload.GetInstanceID())
					m_dictTextureData.Add(item.Key, item.Value);
			}
			
			Resources.UnloadAsset(rTextureToUnload);
			m_dictTextures.Remove(strTextureName);
			
			rTextureToUnload = null;
			dictTextureDataCopy = null;
		}
		else if(Debug.isDebugBuild)
			Debug.LogError("CM_TextureManager.UnloadTexture: impossibile trovare il file " + strTextureName);
	}
	
	public TextureInfo GetTextureInfo(string strTextureName)
	{
		TextureInfo rRVal = null;
		
		string[] splittedName = strTextureName.Split('/');
		
		if(!m_dictTextureData.TryGetValue(splittedName[splittedName.Length-1], out rRVal))
		{
			// se la texture non è stata precedentemente caricata con un texture atlas allora cerco la texture singola
			Texture rTexture = (Texture)Resources.Load(strTextureName, typeof(Texture));
			if(rTexture != null)
			{
				rRVal = new TextureInfo();
				rRVal.m_rTextureAtlas = rTexture;
				rRVal.m_rectNormalizedFrame = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
				rRVal.m_rectSpriteSourceSize = new Rect(0.0f, 0.0f, rTexture.width*BM_Utils.ScaleFactor, rTexture.height*BM_Utils.ScaleFactor);
				rRVal.m_bTrimmed = false;
				m_dictTextureData.Add(splittedName[splittedName.Length-1], rRVal);
				
				m_dictTextures.Add(splittedName[splittedName.Length-1], rTexture);
			}
			else if(Debug.isDebugBuild)
				Debug.LogError("SV_TextureManager.GetTextureInfo: " + strTextureName + " inesistente!");
		}
		
		return rRVal;
	}
	
	#region Singleton
	
	private static BM_TextureManager m_rManagerReference = null;
	
	public static BM_TextureManager Instance()
	{
		if(m_rManagerReference == null)
		{
			Debug.LogError("SV_TextureManager.Instance() -> Manager non inizializzato! ERRORE!");
			Debug.DebugBreak();
		}
		
		return m_rManagerReference;
	}
	
	#endregion
}